﻿#region File Description
//-----------------------------------------------------------------------------
// DanielScreen.cs
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using kinect_music_shooter.GameWorld;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Nui.Vision;
#endregion

namespace kinect_music_shooter.Screens
{
    class DanielMenuScreen : GameScreen
    {
        #region Fields

        ContentManager content;
        SpriteFont gameFont;

        //Handtrackerzeugs
        bool KinectIsConnected = true;

        //kinect_music_shooter.Tracking.NuiHandTracker _handTracker;
        NuiUserTracker _skeleton;
        NuiUser firstuser;

        readonly int IMAGE_WIDTH;
        readonly int IMAGE_HEIGHT;
        int width = 830;
        int height = 420;

        Vector2 textPosition = new Vector2(100, 100);
        float posX = 415, posY = 210;
        float cordX = 0, cordY = 0;
        bool _isPainting = true;

        double countdownTimer = 2.0; //2 sekonds
        Camera camera = new Camera();
        public List<Ball> allBalls = new List<Ball>(MAX_BALLS);
        public List<Ball> activeBalls = new List<Ball>(MAX_BALLS);
        public List<Shot> allShots = new List<Shot>(MAX_SHOTS);
        public List<Shot> activeShots = new List<Shot>(MAX_SHOTS);
        Tunnel tunnel;
        Avatar avatar;
        public static int MAX_BALLS = 1000;
        public static int MAX_SHOTS = 10000;


        //Audio
        kinect_music_shooter.Audio.MusicGraph musicGraph;
        double[] m_startInSector = new double[8];

        Random random = new Random();

        float pauseAlpha;

        #endregion

        #region Initialization

        public DanielMenuScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            musicGraph = new Audio.MusicGraph();

            try
            {
                _skeleton = new NuiUserTracker("SamplesConfig.xml");
                _skeleton.UserUpdated += new NuiUserTracker.UserUpdatedHandler(Skeleton_UserUpdated);

                //_handTracker = new kinect_music_shooter.Tracking.NuiHandTracker("SamplesConfig.xml");
                //_handTracker.Hover += new kinect_music_shooter.Tracking.NuiHandTracker.HoverHandler(Hands_Hover);
                //_handTracker.Push += new kinect_music_shooter.Tracking.NuiHandTracker.PushHandler(Hands_Push);

                //IMAGE_WIDTH = _handTracker.Width;
                //IMAGE_HEIGHT = _handTracker.Height;
            }
            catch (Exception)
            {
                KinectIsConnected = false;
            }
        }

        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");


            gameFont = content.Load<SpriteFont>("gamefont");

            Model ballModel = content.Load<Model>("Meshes/ball");

            for (int i = 0; i < MAX_BALLS; i++)
            {
                allBalls.Add(new Ball());
            }

            foreach (Ball ball in allBalls)
            {
                ball.loadModel(ballModel);
            }
            BasicEffect effect = new BasicEffect(ScreenManager.GraphicsDevice);
            for (int i = 0; i < MAX_SHOTS; i++)
            {
                allShots.Add(new Shot(ScreenManager.GraphicsDevice, effect));
            }

            foreach (Shot shot in allShots)
            {
                //shot.loadModel(ballModel);
                shot.LoadTexture(content.Load<Texture2D>("shot"));
            }

            tunnel = new Tunnel();
           
            tunnel.loadModel(content.Load<Model>("Meshes/tunnel"));
            //tunnel.rotation = new Vector3(MathHelper.PiOver2, 0, 0);

            avatar = new Avatar();
            avatar.loadModel(ScreenManager.GraphicsDevice, content.Load<Model>("Meshes/bodypart"));

            camera.Position = new Vector3(0.0f, 0.0f, -20.0f);
            camera.Target = new Vector3(0f, 0f, 0f);
            camera.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, ScreenManager.GraphicsDevice.Viewport.AspectRatio, 10f, 10000f);

            ScreenManager.Game.ResetElapsedTime();
        }

        public override void UnloadContent()
        {
            content.Unload();
        }

        #endregion

        #region Update and Draw

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            if (IsActive)
            {
                for (int i = 0; i < activeShots.Count; i++)
                {
                    activeShots[i].Update();
                    if (activeShots[i].position.Z > 3000.0f)
                    {
                        KillShot(i);
                    }
                }

                for (int i = 0; i < activeBalls.Count; i++)
                {
                    activeBalls[i].Update();
                    if (activeBalls[i].position.Z < -20.0f)
                    {
                        KillBall(i);
                    }
                }

                for (int i = 0; i < activeBalls.Count && i>=0; i++)
                {
                    for (int j = 0; j < activeShots.Count && i>=0; j++)
                    {
                        if (activeShots[j].boundingSphere.Intersects(activeBalls[i].boundingSphere))
                        {
                            KillShot(j);
                            KillBall(i);
                            i--;
                            j--;
                        }
                    }
                }

                if (avatar.wurf())
                {
                    AddShot(avatar.getWurfVector());
                }

                tunnel.Update();
                musicGraph.setBlockTime(1.5);
                AddBall(musicGraph.get_PeaksByTime());
            }
        }

        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected && input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
            else
            {
                // Otherwise move the player position.
                Vector2 movement = Vector2.Zero;

                if (keyboardState.IsKeyDown(Keys.Left))
                    AddShot(new Vector3(0.2f,0.0f,1));

                if (keyboardState.IsKeyDown(Keys.Right))
                    AddShot(new Vector3(-0.2f, 0.0f, 1));

                if (keyboardState.IsKeyDown(Keys.Up))
                    AddShot(new Vector3(0, 0.2f, 1));

                if (keyboardState.IsKeyDown(Keys.Down))
                    AddShot(new Vector3(0, -0.2f, 1));

                Vector2 thumbstick = gamePadState.ThumbSticks.Left;

                movement.X += thumbstick.X;
                movement.Y -= thumbstick.Y;

                if (movement.Length() > 1)
                    movement.Normalize();

                //playerPosition += movement * 2;
            }
        }

        public override void Draw(GameTime gameTime)
        {
            cordX = posX - (width / 2);
            cordY = -(posY - (height / 2));

            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target, Color.CornflowerBlue, 0, 0);

            tunnel.Draw(ScreenManager.Game.GraphicsDevice, camera);
            for (int i = activeBalls.Count - 1; i >= 0; i--)
            {
                activeBalls[i].Draw(ScreenManager.Game.GraphicsDevice, camera);
            }
            for (int i = 0; i < activeShots.Count; i++)
            {
                activeShots[i].Draw(ScreenManager.Game.GraphicsDevice, camera);
            }
            // If the game is transitioning on or off, fade it out to black.

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            spriteBatch.Begin();
            spriteBatch.DrawString(gameFont, cordX + " " + cordY, textPosition, Color.DarkBlue);
            spriteBatch.DrawString(gameFont, "X", new Vector2(posX, posY), Color.DarkBlue);
            spriteBatch.DrawString(gameFont, "AllShots:" + allShots.Count.ToString(), new Vector2(400, 300), Color.DarkBlue);
            spriteBatch.DrawString(gameFont, "ActiveShots:" + activeShots.Count.ToString(), new Vector2(400, 350), Color.DarkBlue);

            if (!KinectIsConnected)
            {
                spriteBatch.DrawString(gameFont, "Konnect the kinect", new Vector2(200, 200), Color.Red);
            }
            if (avatar.wurf())
            {
                spriteBatch.DrawString(gameFont, "wurf", new Vector2(300, 300), Color.Red);
            }

            spriteBatch.DrawString(gameFont, avatar.vect().ToString(), new Vector2(300, 350), Color.Red);
            spriteBatch.End();
            avatar.Draw(ScreenManager.Game.GraphicsDevice, camera);
            //DRawUser();


            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }

        #endregion

        private void AddShot(Vector3 direction)
        {
            if (activeShots.Count < MAX_SHOTS && allShots.Count > 0)
            {
                Shot tShot = allShots[allShots.Count - 1];
                direction.Z *= 0.8f;
                direction.Normalize();
                direction *= 2.0f;

                tShot.scale = 2.0f;
                tShot.velocity = direction;
                tShot.position = avatar.RightHand.position;

                allShots.Remove(tShot);
                activeShots.Add(tShot);
            }
        }

        private void KillShot(int index)
        {
            Shot tShot = activeShots[index];
            activeShots.Remove(tShot);
            tShot.scale = 1.0f;
            tShot.position = Vector3.Zero;
            tShot.velocity = Vector3.Zero;
            allShots.Add(tShot);
        }

        private int getSector(double[] pikes)
        {
            int sector = -1;
            if (pikes[0] > 0) sector = 0;
            if (pikes[1] > 0) sector = 1;
            if (pikes[2] > 0) sector = 2;
            if (pikes[3] > 0) sector = 3;
            if (pikes[4] > 0) sector = 4;
            if (pikes[5] > 0) sector = 5;
            if (pikes[6] > 0) sector = 6;
            if (pikes[7] > 0) sector = 7;
            return sector;
        }

        private void AddBall(double[] pikes)
        {
        }

        private void KillBall(int index)
        { }

        #region Tracking

        void Skeleton_UserUpdated(object sender, NuiUserEventArgs e)
        {
            foreach (var user in e.Users)
            {
                firstuser = user;
                avatar.getuser(firstuser);
                float headX = user.Head.X;
                float headY = user.Head.Y;

                float neckX = user.Neck.X;
                float neckY = user.Neck.Y;

                float leftShoulderX = user.LeftShoulder.X;
                float leftShoulderY = user.LeftShoulder.Y;

                float leftElbowX = user.LeftElbow.X;
                float leftElbowY = user.LeftElbow.Y;

                float leftHandX = user.LeftHand.X;
                float leftHandY = user.LeftHand.Y;

                float rightSholuderX = user.RightShoulder.X;
                float rightShoulderY = user.RightShoulder.Y;

                float rightElbowX = user.RightElbow.X;
                float rightElbowY = user.RightElbow.Y;

                float rightHandX = user.RightHand.X;
                float rightHandY = user.RightHand.Y;

                float waistX = user.Torso.X;
                float waistY = user.Torso.Y;

                float leftHipX = user.LeftHip.X;
                float leftHipY = user.LeftHip.Y;

                float leftKneeX = user.LeftKnee.X;
                float leftKneeY = user.LeftKnee.Y;

                float leftFootX = user.LeftFoot.X;
                float leftFootY = user.LeftFoot.Y;

                float rightHipX = user.RightHip.X;
                float rightHipY = user.RightHip.Y;

                float rightKneeX = user.RightKnee.X;
                float rightKneeY = user.RightKnee.Y;

                float rightFootX = user.RightFoot.X;
                float rightFootY = user.RightFoot.Y;





                /* DrawCircle(headX, headY, userColor);
                 DrawCircle(neckX, neckY, userColor);
                 DrawCircle(leftShoulderX, leftShoulderY, userColor);
                 DrawCircle(leftElbowX, leftElbowY, userColor);
                 DrawCircle(leftHandX, leftHandY, userColor);
                 DrawCircle(waistX, waistY, userColor);
                 DrawCircle(rightSholuderX, rightShoulderY, userColor);
                 DrawCircle(rightElbowX, rightElbowY, userColor);
                 DrawCircle(rightHandX, rightHandY, userColor);
                 DrawCircle(leftHipX, leftHipY, userColor);
                 DrawCircle(leftKneeX, leftKneeY, userColor);
                 DrawCircle(leftFootX, leftFootY, userColor);
                 DrawCircle(rightHipX, rightHipY, userColor);
                 DrawCircle(rightKneeX, rightKneeY, userColor);
                 DrawCircle(rightFootX, rightFootY, userColor);*/

            }
        }

        void DRawUser()
        {
            if (firstuser != null)
            {
                SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
                spriteBatch.Begin();
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.Head.X, firstuser.Head.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.Neck.X, firstuser.Neck.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftShoulder.X, firstuser.LeftShoulder.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftElbow.X, firstuser.LeftElbow.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftHand.X, firstuser.LeftHand.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightShoulder.X, firstuser.RightShoulder.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightElbow.X, firstuser.RightElbow.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightHand.X, firstuser.RightHand.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.Torso.X, firstuser.Torso.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftHip.X, firstuser.LeftHip.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftKnee.X, firstuser.LeftKnee.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.LeftFoot.X, firstuser.LeftFoot.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightHip.X, firstuser.RightHip.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightKnee.X, firstuser.RightKnee.Y), Color.DarkBlue);
                spriteBatch.DrawString(gameFont, "O", new Vector2(firstuser.RightFoot.X, firstuser.RightFoot.Y), Color.DarkBlue);
                spriteBatch.End();

                avatar.DrawLine(new Vector2(firstuser.Head.X, firstuser.Head.Y), new Vector2(firstuser.Neck.X, firstuser.Neck.Y), Color.AliceBlue, ScreenManager);
            }

        }

        #endregion
    }
}